/*
 * Copyright (c) 2018 Hitevision
 */

package tw.com.hitevision.whiteboard.android.display;

import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Process;
import android.util.Log;

import com.hht.middleware.model.SourceValue;
import com.hht.sdk.source.HHTSourceManager;
import com.ist.android.tv.IstEventManager;
import com.ist.android.tv.IstSourceManager;
import com.mstar.android.tv.TvCommonManager;
import com.ist.android.tv.IstCustomerManager;
import com.mstar.android.tvapi.common.TvManager;
import com.mstar.android.tvapi.common.exception.TvCommonException;
import com.mstar.android.tvapi.common.vo.TvOsType;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import tw.com.hitevision.whiteboard.android.Props;
import tw.com.hitevision.whiteboard.android.util.ActivityUtils;
import tw.com.hitevision.whiteboard.android.util.BroadcastHelper;
import tw.com.hitevision.whiteboard.android.util.SystemPropertiesUtils;

public class DisplayControlImpl implements DisplayControl {
    private static final String TAG = DisplayControl.class.getSimpleName();

    private static final int RECT_ID_INVALID = -2; // -1 is a valid value for VN
    private static final int RECT_ID_X9 = 1;
    private static final int RECT_ID_OTHER = 1;

    private static final int DEVICE_TYPE_X9 = 1;
    private static final int DEVICE_TYPE_OTHER = 2;

    private static final long START_DELAY = 2000; // ms

    private TvManager tvManager;
    private IstCustomerManager istCustomerManager;
    private HHTSourceManager hhtSourceManager;
    private int rectId;
    private int deviceType;
    private Rect disabledRect;
    private boolean isRunning;
    private Handler handler;

    private int startStopCounter;
    private final boolean isXvnModel;
    private final boolean isMainboard848;
    private final boolean isMainboard828;
    private final boolean isHisi;

    private boolean isSupported;

    private Intent intent;
    public static final String USBTOUCH_DISABLE = "com.hht.action.USBTOUCH.DISABLE";
    public static final String USBTOUCH_ENABLE = "com.hht.action.USBTOUCH.ENABLE";
    public static final String isSetOnButton = "is_set_on_button";


    /*
     !!!!!!!!!!
     ReqUsbControl 1 & 2 are no longer using on Mstar Chipset
     or you will intermingle the system control
     !!!!!!!!!!

     ReqUsbControl 1, this make USB touch enabled in windows, when exit annotation
     or push the toggle control button, need to send this

     ReqUsbControl 2, this make USB touch disabled in windows, when annotation start
     or recover the toggle control, need to send this.

     ReqUsbControl 3, this initial the rect mark zone, when annotation launched, call this
     to initial the mark zone, if this mark zone enabled, then even the USB touch enabled by
     ReqUsbControl 1, touch will not pass through to windows at the bottom bar area.

     ReqUsbControl 4, this used to update the mark zone size and position, when show/hide
     the bottom bar, use this.

     ReqUsbControl 5, this used to release the mark zone, need to use the rectID from ReqUsbControl 3,
     the rectID must be correct, the the mark zone will be released correctly

     You must send ReqUsbControl 2 after sent ReqUsbControl 1.
     You must send ReqUsbControl 5 after sent ReqUsbControl 3.
     If you don't follow above 2 rules, DisplayControl will crash.
     ReqUsbControl 4 is used to update the mark zone initialized by ReqUsbControl 3.

     */

    DisplayControlImpl(Context context) {
        isHisi = Props.getFlavorChipset().equals(Props.Flavor.Chipset.Hisi);

        if (isHisi) {
            istCustomerManager = IstCustomerManager.getInstance();
            isSupported = true;
        } else {
            try {
                tvManager = TvManager.getInstance();
                isSupported = true;
            } catch (UnsatisfiedLinkError e) {
                e.printStackTrace();
                isSupported = false;
            }
        }

        hhtSourceManager = new HHTSourceManager(context);

        isRunning = false;
        rectId = RECT_ID_INVALID;
        disabledRect = new Rect();
        handler = new Handler();
        isXvnModel = Props.getFlavorModel().equals(Props.Flavor.Model.Xvn);
        isMainboard848 = Props.getMainboardVersion() == Props.Mainboard.V_848;
        isMainboard828 = Props.getMainboardVersion() == Props.Mainboard.V_828;

        final String type = SystemPropertiesUtils.getStringValue(SystemPropertiesUtils.KEY_DEVICE_TYPE, "0");
//        deviceType = "1".equals(type) ? DEVICE_TYPE_X9 : DEVICE_TYPE_OTHER;
        if( "1".equals(type)) {
            deviceType = DEVICE_TYPE_X9;
        } else {
            deviceType = DEVICE_TYPE_OTHER;
        }
    }

    @Override
    public boolean isX9DeviceType() {
        return deviceType == DEVICE_TYPE_X9 && !isMainboard848;
    }

    /**
     * Returns {@code true} if screen control is supported on current device.
     */
    @Override
    public boolean isSupported(Context context) {
        if (isHisi) {
//            boolean result = isControllableInputShowing(context);
//            return isSupported && istCustomerManager != null && result;
            return true;
        } else if(Props.getFlavorModel().equals(Props.Flavor.Model.Oem)){
            return true;
        } else {
            return isSupported && tvManager != null && isControllableInputShowing(context);
        }
    }

    private boolean isControllableInputShowing(Context context) {
        if (isHisi) {
//            // android system : ANDROID
//            // ops : OPS
//            String str = IstSourceManager.getInstance().getCurSourceChannel();
//            return IstSourceManager.getInstance() != null && str != null && str.equals("OPS");
            final List<ActivityManager.RunningTaskInfo> tasks = ActivityUtils.getRunningTasks(context, 4);
            int taskCount = 0;
            boolean pcIsTop = false;
            for (ActivityManager.RunningTaskInfo task : tasks) {
                final String activityName = task.topActivity.flattenToString();
                if (activityName.equals(ActivityUtils.ACTIVITY_PC) || activityName.equals(ActivityUtils.ACTIVITY_PC_2)
                        || activityName.equals(ActivityUtils.ACTIVITY_PC_HISI)) {
                    pcIsTop = taskCount <= 1;
                    break;
                }
                taskCount++;
            }
            return pcIsTop;
        } else if (isMainboard828 && isXvnModel) {// avoid 828 return wrong boolean (firmware vision 20200813)
            if (Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
                final List<ActivityManager.RunningTaskInfo> tasks = ActivityUtils.getRunningTasks(context, 4);
                int taskCount = 0;
                boolean pcIsTop = false;
                for (ActivityManager.RunningTaskInfo task : tasks) {
                    final String activityName = task.topActivity.flattenToString();
                    if (activityName.equals(ActivityUtils.ACTIVITY_PC)
                            || activityName.equals(ActivityUtils.ACTIVITY_PC_2)) {
                        pcIsTop = taskCount <= 1;
                        break;
                    }
                    taskCount++;
                }

                boolean tvIsntStorage = TvCommonManager.getInstance().getCurrentInputSource() != TvOsType.EnumInputSource.E_INPUT_SOURCE_STORAGE;

                return tvIsntStorage && pcIsTop;
            } else {
                // if the current input source is Storage, it means in Android instead of PC
                return TvCommonManager.getInstance().getCurrentInputSource() != TvOsType.EnumInputSource.E_INPUT_SOURCE_STORAGE;
            }
        } else if (!isMainboard848 && isXvnModel) {
            final List<ActivityManager.RunningTaskInfo> tasks = ActivityUtils.getRunningTasks(context, 4);
            for (ActivityManager.RunningTaskInfo task : tasks) {
                final String activityName = task.topActivity.flattenToString();
                if (activityName.equals(ActivityUtils.ACTIVITY_PC)
                        || activityName.equals(ActivityUtils.ACTIVITY_PC_2)) {
                    return true;
                }
            }
            return false;
        } else {
            final List<ActivityManager.RunningTaskInfo> tasks = ActivityUtils.getRunningTasks(context, 4);
            int taskCount = 0;
            boolean pcIsTop = false;
            for (ActivityManager.RunningTaskInfo task : tasks) {
                final String activityName = task.topActivity.flattenToString();
                if (activityName.equals(ActivityUtils.ACTIVITY_PC)
                        || activityName.equals(ActivityUtils.ACTIVITY_PC_2)) {
                    pcIsTop = taskCount <= 1;
                    break;
                }
                taskCount++;
            }

            boolean tvIsntStorage = TvCommonManager.getInstance().getCurrentInputSource() != TvOsType.EnumInputSource.E_INPUT_SOURCE_STORAGE;

            return tvIsntStorage && pcIsTop;

        }
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }

    @Override
    public void setDisabledBounds(int x, int y, int width, int height) {
        if (!isSupported) {
            return;
        }
        if (Props.isFake4k() && !Props.getFlavorChipset().equals(Props.Flavor.Chipset.Hisi)) {
            x /= 2;
            y /= 2;
            width /= 2;
            height /= 2;
        }
        log("setDisabledBounds: x=" + x + ", y=" + y + ", width= " + width + ", height=" + height);
        disabledRect.set(x, y, x + width, y + height);


        if (isRunning) {
            if (!isHisi && !isMainboard848 && (deviceType == DEVICE_TYPE_X9)) {
                initOrUpdateX9RectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                        disabledRect.bottom);
            } else {
                initOrUpdateOpsRectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                        disabledRect.bottom);
            }
        }
    }

    @Override
    public void start(Context context) {
        if (!isSupported) {
            return;
        }

        log("start");

        startControl(context, 0);
    }

    @Override
    public void startFromOnResume(Context context) {
        if (!isSupported) {
            return;
        }

        log("startFromOnResume");

        startControl(context, START_DELAY);
    }

    private void startControl(Context context, long tpSourceDelayInMillis) {
        log("startControl: startStopCounter=" + startStopCounter);
        if (!isSupported(context) && startStopCounter == 0) {
            return;
        }

        startStopCounter++;
        isRunning = true;

        log("- rectId=" + rectId);
        log("- disabledRect=" + disabledRect);
        if (!isHisi && !isMainboard848 && (deviceType == DEVICE_TYPE_X9)) {
            setX9EnableTouch(context);
            initOrUpdateX9RectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                    disabledRect.bottom);
        } else {
            if (rectId != RECT_ID_INVALID) {
                // cancel previous rect that wasn't canceled already for some reason
                cancelOpsRectDisableTouch();
            }

            setOpsEnableTouch(context);
            initOrUpdateOpsRectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                    disabledRect.bottom);

            setTpSourceId();
        }

        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
            if (isInFrontOfPcActivity(context)) {
                handler.removeCallbacks(startTpSourceRunnable);
                handler.postDelayed(startTpSourceRunnable, tpSourceDelayInMillis);
            }
        }

        BroadcastHelper.sendDisplayControlStart(context);
    }

    private Runnable startTpSourceRunnable = () -> {
        hhtSourceManager.changeTPSource(hhtSourceManager.getTopSourceOrdinal(), 0);
    };

    @Override
    public void stop(Context context) {
        if (!isSupported) {
            return;
        }

        log("stop: startStopCounter=" + startStopCounter);
        if (!isSupported(context) && startStopCounter == 0) {
            return;
        }

        startStopCounter--;

        log("- rectId=" + rectId);
        log("- disabledRect=" + disabledRect);
        if (!isHisi && !isMainboard848 && (deviceType == DEVICE_TYPE_X9)) {
            if (rectId != RECT_ID_INVALID) {
                cancelX9RectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                        disabledRect.bottom);
                setX9DisableTouch(context);
            }
        } else {
            if (rectId != RECT_ID_INVALID) {
                cancelOpsRectDisableTouch();
            }
            setOpsDisableTouch(context);

            setTpSourceStorage();
        }

        isRunning = false;
        rectId = RECT_ID_INVALID;

        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
            if (isInFrontOfPcActivity(context)) {
                handler.removeCallbacks(startTpSourceRunnable);
                hhtSourceManager.changeTPSource(SourceValue.ANDROID_ORDINAL, 0);
            }
        }

        BroadcastHelper.sendDisplayControlEnd(context);
    }

    @Override
    public void cancel(Context context) {
        if (!isSupported) {
            return;
        }

        log("cancel: startStopCounter=" + startStopCounter);
        if (!isSupported(context) && rectId == RECT_ID_INVALID) {
            return;
        }

        startStopCounter = 0;

        log("- rectId=" + rectId);
        log("- disabledRect=" + disabledRect);

        if (!isHisi && !isMainboard848 && (deviceType == DEVICE_TYPE_X9)) {
            if (rectId != RECT_ID_INVALID) {
                cancelX9RectDisableTouch(disabledRect.left, disabledRect.top, disabledRect.right,
                        disabledRect.bottom);
            }
        } else {
            if (rectId != RECT_ID_INVALID) {
                cancelOpsRectDisableTouch();
            }
        }

        isRunning = false;
        rectId = RECT_ID_INVALID;

        BroadcastHelper.sendDisplayControlEnd(context);
    }

    private void setTpSourceId() {
        log("setTpSourceId");
        if (isHisi) {
            final String curInputSrc = IstSourceManager.getInstance().getCurSourceChannel();
            istCustomerManager.setTvosCommonCommand("SetTpSource " + curInputSrc);
        } else
        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
            if (isMainboard848 || !isXvnModel) {
                try {
                    final int curInputSrc = tvManager.getCurrentInputSource().ordinal();
                    tvManager.setTvosCommonCommand("SetTpSource " + curInputSrc);
                } catch (TvCommonException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void setTpSourceStorage() {
        log("setTpSourceStorage");
        if (isHisi) {
            istCustomerManager.setTvosCommonCommand("SetTpSource " + TvOsType.EnumInputSource.E_INPUT_SOURCE_STORAGE.ordinal());
        } else
        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
            if (isMainboard848 || !isXvnModel) {
                try {
                    tvManager.setTvosCommonCommand("SetTpSource " + TvOsType.EnumInputSource.E_INPUT_SOURCE_STORAGE.ordinal());
                } catch (TvCommonException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // X9

    /**
     * Enables display control for X9 units.
     */
    private void setX9EnableTouch(Context context) {
        log("setX9EnableTouch");

        try {
            log("- result=" + tvManager.WriteCmdToTVOS("ENABLE_ALL_USB_MASK_ZONE", ""));
        } catch (TvCommonException e) {
            e.printStackTrace();
        }
    }

    /**
     * Disables display control for X9 units.
     */
    private void setX9DisableTouch(Context context) {
        log("setX9DisableTouch");

        try {
            log("- result=" + tvManager.WriteCmdToTVOS("DISABLE_ALL_USB_MASK_ZONE", ""));
        } catch (TvCommonException e) {
            e.printStackTrace();
        }
    }

    private void initOrUpdateX9RectDisableTouch(int left, int top, int right, int bottom) {
        log("initOrUpdateX9RectDisableTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);
        if (rectId == RECT_ID_INVALID) {
            rectId = initX9DisableRectTouch(left, top, right, bottom);
            log("- rectId=" + rectId);
        } else {
            updateX9DisableRectTouch(left, top, right, bottom);
        }
    }

    /**
     * Initializes disabled control area for X9 units.
     */
    private int initX9DisableRectTouch(int left, int top, int right, int bottom) {
        log("initX9DisableRectTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);
        final String cmd = String.format(Locale.US, "%d|%d,%d,%d,%d", RECT_ID_X9, left, top, right, bottom);

        try {
            log("- result=" + tvManager.WriteCmdToTVOS("SetMask->", cmd));
        } catch (TvCommonException e) {
            e.printStackTrace();
        }
        return RECT_ID_X9;
    }

    /**
     * Updates disabled control area for X9 units.
     */
    private void updateX9DisableRectTouch(int left, int top, int right, int bottom) {
        log("updateX9DisableRectTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);
        final String cmd = String.format(Locale.US, "%d|%d,%d,%d,%d", rectId, left, top, right, bottom);

        try {
            log("- result=" + tvManager.WriteCmdToTVOS("ChangeMask->", cmd));
        } catch (TvCommonException e) {
            e.printStackTrace();
        }
    }

    private void cancelX9RectDisableTouch(int left, int top, int right, int bottom) {
        log("cancelX9RectDisableTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);

        final String cmd = String.format(Locale.US, "%d|%d,%d,%d,%d", rectId, left, top, right, bottom);
        try {
            log("- result=" + tvManager.WriteCmdToTVOS("ReleaseMask->", cmd));
        } catch (TvCommonException e) {
            e.printStackTrace();
        }
    }

    // OPS

    /**
     * Enables display control for non-X9 units.
     */
    private void setOpsEnableTouch(Context context) {
        log("setOpsEnableTouch");
        if (isHisi) {
            final String cmd;
            cmd = String.format(Locale.US, "ReqUsbControl 1 %d", Process.myPid());

            log("- cmd: " + cmd);
            log("- result=" + istCustomerManager.setTvosCommonCommand(cmd));
        } else
        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
//            no longer use
//            final String cmd;
//            if (!isMainboard848 && isXvnModel) {
//                cmd = "ReqUsbControl 1";
//            } else {
//                cmd = String.format(Locale.US, "ReqUsbControl 1 %d", Process.myPid());
//            }
//
//            log("- cmd: " + cmd);
//            try {
//                log("- result=" + Arrays.toString(tvManager.setTvosCommonCommand(cmd)));
//            } catch (TvCommonException e) {
//                e.printStackTrace();
//            }
        } else {
//            if (intent != null) {
//                log("DisplayControl : send broadcast : " + intent.getAction());
//                log("DisplayControl : is_set_on_button : " + intent.getBooleanExtra(isSetOnButton, false));
//                context.sendBroadcast(intent);
//                intent = null;
//            }

        }
    }

    /**
     * Disables display control for non-X9 units.
     */
    private void setOpsDisableTouch(Context context) {
        if (isHisi) {
            log("setOpsDisableTouch");

            final String cmd;
            cmd = String.format(Locale.US, "ReqUsbControl 2 %d", Process.myPid());

            log("- cmd: " + cmd);
            log("- result=" + istCustomerManager.setTvosCommonCommand(cmd));
        } else
        if (!Props.getFlavorModel().equals(Props.Flavor.Model.NewlineChinaYi)) {
            //no longer use
//            log("setOpsDisableTouch");
//
//            final String cmd;
//            if (!isHisi && !isMainboard848 && (isXvnModel )) {
//                cmd = "ReqUsbControl 2";
//            } else {
//                cmd = String.format(Locale.US, "ReqUsbControl 2 %d", Process.myPid());
//            }
//
//            log("- cmd: " + cmd);
//            try {
//                log("- result=" + Arrays.toString(tvManager.setTvosCommonCommand(cmd)));
//            } catch (TvCommonException e) {
//                e.printStackTrace();
//            }
        } else {
//            if (intent != null) {
//                log("DisplayControl : send broadcast : " + intent.getAction());
//                log("DisplayControl : is_set_on_button : " + intent.getBooleanExtra(isSetOnButton, false));
//                context.sendBroadcast(intent);
//                intent = null;
//            }

        }
    }

    /**
     * Initializes or updates disabled control area for non-X9 units.
     */
    private void initOrUpdateOpsRectDisableTouch(int left, int top, int right, int bottom) {
        log("initOrUpdateOpsRectDisableTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);

        if (left == 0 && top == 0 && right == 0 && bottom == 0 && !isHisi) {
            return; // do nothing since bounds not set
        }

        if (rectId == RECT_ID_INVALID) {
            rectId = initOpsRectDisableTouch(left, top, right, bottom);
            log("- rectId=" + rectId);
        } else {
            updateOpsRectDisableTouch(left, top, right, bottom);
        }
    }

    /**
     * Initializes disabled control area for non-X9 units.
     *
     * @return disabled control area's rectId
     */
    private int initOpsRectDisableTouch(int left, int top, int right, int bottom) {
        log("initOpsRectDisableTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);

        final String cmd;
        if (isHisi) {
            cmd = String.format(Locale.US, "9| %d,%d,%d,%d", left / 2, top / 2, right / 2, bottom / 2);
        } else if (!isMainboard848 && (isXvnModel)) {
            cmd = String.format(Locale.US, "ReqUsbControl 3 (%d,%d,%d,%d)",
                    left, top, right - left, bottom - top);
        } else {
            cmd = String.format(Locale.US, "ReqUsbControl 3 (%d,%d,%d,%d) %d",
                    left, top, right - left, bottom - top, Process.myPid());
        }

        log("- cmd: " + cmd);
        if (isHisi) {
//            int result = istCustomerManager.setTvosCommonCommand(cmd);
            IstEventManager istEventManager = IstEventManager.getInstance();
            if (istEventManager != null) {
                int result = istEventManager.WriteCmdAreaStrToTVOS(cmd);
                log("- result=" + result);
                return result;
            }
        } else {
            try {
                short[] result = tvManager.setTvosCommonCommand(cmd);
                log("- result=" + Arrays.toString(result));
                return result[0];
            } catch (TvCommonException e) {
                e.printStackTrace();
            }
        }
        return RECT_ID_OTHER;

    }

    /**
     * Updates disabled control area for non-X9 units.
     */
    private void updateOpsRectDisableTouch(int left, int top, int right, int bottom) {
        log("updateOpsRectDisableTouch: left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom);

        final String cmd;
        if (isHisi) {
            cmd = String.format(Locale.US, "9| %d,%d,%d,%d", left / 2, top / 2, right / 2, bottom / 2);
        } else if (!isMainboard848 && (isXvnModel)) {
            cmd = String.format(Locale.US, "ReqUsbControl 4 %d (%d,%d,%d,%d)",
                    rectId, left, top, right - left, bottom - top);
        } else {
            cmd = String.format(Locale.US, "ReqUsbControl 4 %d (%d,%d,%d,%d) %d",
                    rectId, left, top, right - left, bottom - top, Process.myPid());
        }

        log("- cmd: " + cmd);
        if (isHisi) {
            IstEventManager istEventManager = IstEventManager.getInstance();
            if (istEventManager != null) {
                int result = istEventManager.WriteCmdAreaStrToTVOS(cmd);
                log("- result=" + result);
            }
        } else {
            try {
                log("- result=" + Arrays.toString(tvManager.setTvosCommonCommand(cmd)));
            } catch (TvCommonException e) {
                e.printStackTrace();
            }
        }
    }

    private void cancelOpsRectDisableTouch() {
        log("cancelOpsRectDisableTouch");

        String cmd = String.format(Locale.US, "ReqUsbControl 5 %d", rectId);
        log("- cmd: " + cmd);
        if (isHisi) {
            cmd = String.format(Locale.US, "9| %d,%d,%d,%d", 0, 0, 0, 0);
            IstEventManager istEventManager = IstEventManager.getInstance();
            if (istEventManager != null) {
                int result = istEventManager.WriteCmdAreaStrToTVOS(cmd);
                log("- result=" + result);
            }
        } else {
            try {
                log("- result=" + Arrays.toString(tvManager.setTvosCommonCommand(cmd)));
            } catch (TvCommonException e) {
                e.printStackTrace();
            }
        }
    }

    private boolean isInFrontOfPcActivity(Context context) {
        final List<ActivityManager.RunningTaskInfo> tasks = ActivityUtils.getRunningTasks(context, 3);
        final int size = tasks.size();

        if (size < 2) {
            return false;
        }

        final String first = tasks.get(1).topActivity.flattenToString();
        if (first.equals(ActivityUtils.ACTIVITY_PC_2)
                || first.equals(ActivityUtils.ACTIVITY_PC)
                || first.equals(ActivityUtils.ACTIVITY_PC_SETTINGS)) {
            return true;
        }

        if (size < 3) {
            return false;
        }

        // special case: bright control bar then full screen input source
        final String second = tasks.get(2).topActivity.flattenToString();
        return first.equals(ActivityUtils.ACTIVITY_BRIGHTNESS_DIALOG)
                && (second.equals(ActivityUtils.ACTIVITY_PC_2) || second.equals(ActivityUtils.ACTIVITY_PC));
    }

    @Override
    public void setIntent(Intent intent) {
        this.intent = intent;
    }


    private static void log(String msg) {
        Log.d(TAG, msg);
    }
}
